import { System } from 'cc';
import { log } from 'cc';
import { sys } from 'cc';
import { Eventify } from 'cc';
import { director } from 'cc';
import { _decorator, Component, Node } from 'cc';
import { ReactiveProperty } from '../../libs/rxjs/cc3/ReactiveProperty';
import { of } from '../../libs/rxjs/internal/observable/of';
import { Observable } from '../../libs/rxjs/internal/Observable';
import { Subscription } from '../../libs/rxjs/internal/Subscription';
import { nullifySubscription } from '../../libs/rxjs/utils';
import { concat } from '../../libs/rxjs/internal/observable/concat';
import { map } from '../../libs/rxjs/internal/operators/map';
import { defer } from '../../libs/rxjs/internal/observable/defer';
import { js } from 'cc';
import { am } from '../../managers/AudioManager';
import { udm } from '../../managers/UserDataManager';
import { Timer } from '../../libs/rxjs/cc3/CreatorSchedule';
import { DevConfig } from '../../managers/DevConfig';
const { ccclass, property } = _decorator;


const WeChatRewardAdUnitId = "adunit-8f5dc9c6f6648539"; //激励广告位id
const WeChatInterstitialUnitId = "adunit-f6ba27cce57d6ecc"; //插屏广告位id
const WeChatBannerUnitId = "adunit-8ea6cd6320f5372b" // banner广告位id

declare const wx;

@ccclass('WeChatVideoAdManager')
export class WeChatVideoAdManager extends Eventify(System) {

    public static instance: WeChatVideoAdManager;
    static ID = 'WeChat_system';

    registerSystem() {
        director.unregisterSystem(director.getSystem(WeChatVideoAdManager.ID));
        director.registerSystem(WeChatVideoAdManager.ID, wcadm, System.Priority.MEDIUM);
        wcadm.init();
    }

    init() {
        log(`<${js.getClassName(this)}>`, 'init');

        if (sys.platform == sys.Platform.WECHAT_GAME) {
            this.WeChatVideoAdInit();
        }
    }

    running: ReactiveProperty<boolean> = new ReactiveProperty<boolean>().init(false);

    showAds() {
        if (this.running.value) {
            return of(null);
        } else {
            return new Observable(observer => {
                if (!DevConfig.adFakeProcess) {
                    this.running.value = true;
                    // am.pauseBgm();
                    wcadm.videoAdInit(() => {
                        this.running.value = false;
                        this.lastVideoAdTs = Date.parse(new Date().toString());
                        observer.next(true);
                        observer.complete();
                        Timer(.5).subscribe(_ => udm.bgmOn.again());
                    }, () => {
                        this.running.value = false;
                        this.lastVideoAdTs = Date.parse(new Date().toString());
                        observer.next(false);
                        observer.complete();
                        Timer(.5).subscribe(_ => udm.bgmOn.again());
                    });
                    wcadm.WeChatVideoAdShow();
                } else {
                    this.running.value = true;

                    globalThis.GameManager.instance.frontTipShow('获得奖励').subscribe();

                    setTimeout(() => {
                        this.running.value = false;
                        observer.next(true);
                        observer.complete();
                    }, 500);
                }
            });
        }
    }

    private videoAdInit(success, failed) {
        this.callBackSuccess = success;
        this.callBackFailed = failed;
    }

    private callBackSuccess: any = null;     //成功播放回调函数
    private callBackFailed: any = null;      //失败播放回调函数
    private rewardedVideoAd: any = null;     //激励广告实例

    //广告成功播放结束
    private videoAdSuccess() {
        if (this.callBackSuccess != null) {
            this.callBackSuccess.call(this);
        }
    }
    //广告播放失败（提前关闭）
    private videoAdFailed() {
        if (this.callBackFailed != null) {
            this.callBackFailed.call(this);
        }
    }

    /**
     * 抖音广告插件
     */
    public WeChatVideoAdInit() {

        console.log("抖音广告组件初始化");
        let self = this;

        this.rewardedVideoAd = globalThis.wx.createRewardedVideoAd({
            adUnitId: WeChatRewardAdUnitId,                           //广告位 id，后续可以在平台基于广告位id看数
            // multiton: true,                                  //是否开启再得广告模式（只支持安卓系统的抖音和抖音极速版）
            // multitonRewardedMsg: "观看下一个可领取更多奖励",   //再得广告的奖励文案，玩家每看完一个广告都会展示，如【再看1个获得xx】xx就multitonRewardMsg中的文案，按顺序依次展示，单个文案最大长度为 7multiton为true时必填
            // multitonRewardTimes:5,                           //额外观看广告的次数，合法的数据范围为1-4，multiton为true时必填
            // progressTip:false,                               //是否开启进度提醒，开启时广告文案为【再看N个获得xx】，关闭时为【 再看1个获得xx】。N表示玩家当前还需额外观看广告的次数。
        });

        //监听错误信息
        this.rewardedVideoAd.onError(function (res) {
            console.log("播放广告失败:", res.errCode, res.errMsg);
        });

        //
        this.rewardedVideoAd.onClose(function (res) {
            console.log("播放广告结束:", res);
            if (res.isEnded) {
                console.log("播放广告结束,可以领取奖励");
                //  self.callBackSuccess.call(this);
                self.videoAdSuccess();
            } else {
                console.log("播放广告结束,不可以领取奖励");
                self.callBackFailed.call(this);
                self.videoAdFailed();
            }
        });
    }

    public WeChatVideoAdLoad() {
        this.rewardedVideoAd.load().then(() => {
            console.log("手动独立加载成功");
        });
    }

    public WeChatVideoAdShow() {
        let self = this;

        //手动加载广告
        // this.rewardedVideoAd.load().then(() => {
        //     console.log("手动加载成功");
        //     this.rewardedVideoAd.show();
        // });

        //广告展示
        this.rewardedVideoAd.show().then(() => {
            console.log("视频广告展示");
        }).catch((err) => {
            console.log("广告组件出现问题", err);
            // 可以手动加载一次
            self.rewardedVideoAd.load().then(() => {
                console.log("手动加载成功");
                // 加载成功后需要再显示广告
                self.rewardedVideoAd.show();
            });
        });
    }

    // InterstitiaAd
    private interstitiaAd: any = null;     //激励广告实例
    firstLaunchTs: number = null;
    lastVideoAdTs: number = null;
    interstitia_running = false;

    interstitialLimitDate = new Date('2023/03/26 00:00:00');
    isOverLimitDate() { // true 开始加广告，false 跳过广告
        return new Date().valueOf() - this.interstitialLimitDate.valueOf() >= 0;
    }

    isTimeEnough() {
        return true; // 去除间隔时间限制
        let curTs = Date.parse(new Date().toString()) / 1000;
        let lastTs = this.lastVideoAdTs / 1000;
        if (curTs - lastTs < 60) {
            console.log("上一次播放广告时间戳：", lastTs, " 当前时间戳：", curTs, " 相差：", curTs - lastTs)
            return false;
        }
        return true;
    }

    firstLaunchEnough() {
        return true; // 去除首次时间限制
        let curTs = Date.parse(new Date().toString()) / 1000;
        let lastTs = this.firstLaunchTs / 1000;
        if (curTs - lastTs < 30) {
            console.log("游戏启动时间：", lastTs, " 当前时间戳：", curTs, " 相差：", curTs - lastTs)
            return false;
        }
        return true;
    }

    _interstitia_sub: Subscription = null;
    public showInterstitial(callback: (result) => void, onShow: () => void) {
        if (sys.platform == sys.Platform.WECHAT_GAME) {
            if (this.interstitia_running) {
                callback(false);
                return false;
            }
            if (!this.isOverLimitDate()) {
                return false;
            }
            if (!this.firstLaunchEnough()) {
                callback(false);
                return false;
            }
            if (!this.isTimeEnough()) {
                callback(false);
                return false;
            }
            nullifySubscription.call(this, '_interstitia_sub');
            if (this.interstitiaAd != null) this.interstitiaAd.destroy();
            this._interstitia_sub = concat(
                of(null).pipe(map(_ => {
                    this.interstitia_running = true;
                    this.interstitiaAd = globalThis.wx.createInterstitialAd({
                        adUnitId: WeChatInterstitialUnitId
                    });
                    this.interstitiaAd.onError((err) => {
                        console.error("插屏广告报错", err, err.errCode, err.errMsg);
                        this.interstitia_running = false;
                        callback(false);
                    })
                    this.interstitiaAd.onClose(() => {
                        console.log("插屏广告关闭");
                        this.lastVideoAdTs = Date.parse(new Date().toString());
                        this.interstitia_running = false;
                        callback(true);
                    })
                })),
                defer(() => this.interstitialOnLoadObserve(this.interstitiaAd)),
                defer(() => new Observable(observer => {
                    this.interstitiaAd.show().then(() => {
                        console.log("插屏广告 展示成功");
                        onShow();
                        observer.next('success');
                        observer.complete();
                    }).catch((err) => {
                        console.error("插屏广告组件出现问题", err);
                        callback(false);
                    });
                }))
            ).subscribe();
        } else {
            globalThis.GameManager.instance.frontTipShow('插屏替代流程，返回成功').subscribe();
            onShow();
            callback(true);
        }
    }

    public destroyInterstitial() {
        nullifySubscription.call(this, '_interstitia_sub');
        if (this.interstitiaAd == null) {
            console.error("没有创建插屏广告实例");
            return;
        } else {
            this.interstitiaAd.destroy();
            this.interstitiaAd = null;
        }
    }

    public interstitialOnLoadObserve(interstitiaAd) {
        return new Observable(observer => {
            let onLoadHandle = () => {
                console.log("插屏广告加载成功");
                observer.next(null);
                observer.complete();
            };
            interstitiaAd.onLoad(onLoadHandle);
            return () => {
                // interstitiaAd.destroy();
            }
        });
    }


    bannerAd = null;

    public initBanner() {
        if (this.bannerAd != null) this.destroyBanner();

        let { windowWidth, windowHeight, screenWidth, screenHeight } = wx.getSystemInfoSync();

        screenWidth = screenWidth ?? windowWidth;
        screenHeight = screenHeight ?? windowHeight


        this.bannerAd = wx.createBannerAd({
            adUnitId: WeChatBannerUnitId,
            adIntervals: 30,
            style: {
                width: 300,
                left: (screenWidth - 300) / 2,
                top: screenHeight - 100,
            }
        });
        this.bannerAd.onLoad(() => {
            console.log('banner 广告加载成功');
        });
        this.bannerAd.onError(err => {
            console.log(err);
        });
        this.bannerAd.onResize(res => {
            console.log('@onResize', res);
            this.bannerAd.style.left = (screenWidth - res.width) / 2;
            this.bannerAd.style.top = screenHeight - res.height;
        });
    }

    public showBanner() {
        if (sys.platform == sys.Platform.WECHAT_GAME) {
            if (this.bannerAd != null) {
                this.bannerAd.show()
                    .then(() => console.log('banner 广告展示'))
                    .catch(err => console.log(err));
            }
        }
    }

    public hideBanner() {
        if (sys.platform == sys.Platform.WECHAT_GAME) {
            if (this.bannerAd != null) {
                this.bannerAd.hide();
            }
        }
    }

    public destroyBanner() {
        if (sys.platform == sys.Platform.WECHAT_GAME) {
            if (this.bannerAd != null) {
                this.bannerAd.destroy();
                this.bannerAd = null;
            }
        }
    }
}

globalThis.WeChatVideoAdManager = WeChatVideoAdManager;

export const wcadm = WeChatVideoAdManager.instance = new WeChatVideoAdManager();